﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Logs;

namespace Communication.Serial {
    /// <summary>
    /// 串口通讯
    /// </summary>
    public class SerialCom {
        private SerialPort seriaPort = new SerialPort();
        private Thread receviceThread = null;
        private Thread sendThread = null;
        private bool keepRecevice = false;
        private bool keepSend = false;
        public event ReceivedData receiveData;
        private SerialProData proData = new SerialProData();

        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        public SerialCom() {
        }

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="param">串口参数</param>
        public SerialCom(SerialParam param) {
            this.seriaPort.PortName = param.PortName;
            this.seriaPort.BaudRate = param.BaudRate;
            this.seriaPort.DataBits = param.DataBits;
            this.seriaPort.StopBits = param.StopBit;
            this.seriaPort.Parity = param.Paritys;
            //this.seriaPort.ReadTimeout = param.ReadTimeout;
            //this.seriaPort.WriteTimeout = param.WriteTimeout;
        }
        #endregion

        #region 打开与关闭串口
        /// <summary>
        /// 打开串口
        /// </summary>
        public void OpenSerial() {
            try {
                //CloseSerial();
                if(!IsOpen) {
                    seriaPort.Open();
                }

                if(IsOpen) {
                    
                    Log.Info(string.Format("启动串口{0} !",this.seriaPort.PortName));
                } else {
                    Log.Info("打开串口失败 !");
                }
            } catch(Exception e) {
                Log.Debug("错误:",e);
            }
        }

        /// <summary>
        /// 关闭串口
        /// </summary>
        public void CloseSerial() {
            StopRecevice();
            seriaPort.Close();
            Log.Info("串口已关闭 !");
        }

        /// <summary>
        /// 读取串口状态，true为打开，false为关闭
        /// </summary>
        public bool IsOpen {
            get {
                return this.seriaPort.IsOpen;
            }
        }
        #endregion

        #region 开始与停止读取
        /// <summary>
        /// 开始接收
        /// </summary>
        public void StartRecevice() {
            if(!keepRecevice) {
                keepRecevice = true;
                receviceThread = new Thread(new ThreadStart(Recevice));
                receviceThread.IsBackground = true;
                receviceThread.Start();
            }
        }

        /// <summary>
        /// 停止接收
        /// </summary>
        public void StopRecevice() {
            if(keepRecevice) {
                keepRecevice = false;
                receviceThread.Join();
                receviceThread = null;
            }
        }
        #endregion

        #region 接收数据
        /// <summary>
        /// 接收数据
        /// </summary>
        private void Recevice() {
            while(keepRecevice) {
                if(!object.ReferenceEquals(Thread.CurrentThread,receviceThread)) {
                    break;
                }
                if(IsOpen) {
                    int count = seriaPort.BytesToRead;
                    if(count > 0) {
                        byte[] readBuff = new byte[count];
                        try {
                            seriaPort.Read(readBuff,0,count);
                            if(receiveData != null) {
                                receiveData(this.seriaPort.PortName,readBuff,count);
                            }
                            Send();
                            Thread.Sleep(200);
                        } catch(Exception e) {
                            Log.Error(string.Format("错误:{0}",e.Message));
                        }
                    } else {
                        Thread.Sleep(1);
                    }
                }
            }
        }
        #endregion

        #region 开始与停止发送
        /// <summary>
        /// 开始发送
        /// </summary>
        public void StartSend() {
            if(!keepSend) {
                keepSend = true;
                sendThread = new Thread(new ThreadStart(Send));
                sendThread.IsBackground = true;
                sendThread.Start();
            }
        }

        /// <summary>
        /// 停止发送
        /// </summary>
        public void StopSend() {
            if(keepSend) {
                keepSend = false;
                sendThread.Join();
                sendThread = null;
            }
        }
        #endregion

        #region 发送数据
        /// <summary>
        /// 发送数据
        /// </summary>
        public void Send() {
            while(keepSend) {
                if(!object.ReferenceEquals(Thread.CurrentThread,sendThread)) {
                    break;
                }
                if(IsOpen) {
                    seriaPort.Write(proData.ProSend(),0,proData.ProSend().Length);
                    Log.Debug(string.Format("成功发送{0}个数据",proData.ProSend().Length));
                    Thread.Sleep(1000);
                }
            }
        }

        #endregion
    }

    public delegate void ReceivedData(string portName,byte[] msg,int msgLen);
}
